import ctypes

class EventHandler:
    def __init__(self, events=None):
        if isinstance(events, EventHandler):
            self.events = events.events.copy()
        else:
            self.events = {}

    def EVENT_COMMAND(self):
        '''OnCommand(self, pEvt)'''
        def _func1(func):
            def _func2(cls, evt):
                func(cls, evt)
            self.events[(10000, None)] = _func2
            return _func2
        return _func1

    def EVENT_ID_COMMAND(self, id):
        '''OnCommand(self)'''
        def _func1(func):
            def _func2(cls, evt):
                func(cls)
            self.events[(10000, id)] = _func2
            return _func2
        return _func1

    def EVENT_ID_RANGE_COMMAND(self, id1, id2):
        '''OnCommand(self, id)'''
        def _func1(func):
            def _func2(cls, evt):
                func(cls, evt.IdFrom())
            self.events[(10000, (id1, id2))] = _func2
            return _func2
        return _func1

    def EVENT_NAME_COMMAND(self, name):
        '''OnCommand(self)'''
        def _func1(func):
            def _func2(cls, evt):
                func(cls)
            if isinstance(name, list):
                for n in name:
                    self.events[(10000, n)] = _func2
            else:
                self.events[(10000, name)] = _func2
            return _func2
        return _func1

    def EVENT_HANDLER(self, code):
        '''OnEvent(self, pEvt)'''
        def _func1(func):
            def _func2(cls, evt):
                func(cls, evt)
            self.events[(code, None)] = _func2
            return _func2
        return _func1

    def EVENT_ID_HANDLER(self, _id, code):
        '''OnEvent(self, pEvt)'''
        def _func1(func):
            def _func2(cls, evt):
                func(cls, evt)
            if isinstance(_id, list):
                for i in _id:
                    self.events[(code, i)] = _func2
            else:
                self.events[(code, _id)] = _func2
            return _func2
        return _func1

    def EVENT_ID_RANGE_HANDLER(self, id1, id2, code):
        '''OnEvent(self, pEvt)'''
        def _func1(func):
            def _func2(cls, evt):
                func(cls, evt)
            self.events[(code, (id1, id2))] = _func2
            return _func2
        return _func1

    def EVENT_NAME_HANDLER(self, name, code):
        '''OnEvent(self, pEvt)'''
        def _func1(func):
            def _func2(cls, evt):
                func(cls, evt)
            if isinstance(name, list):
                for n in name:
                    self.events[(code, n)] = _func2
            else:
                self.events[(code, name)] = _func2
            return _func2
        return _func1

class POINT(ctypes.Structure):
    _fields_ = [('x', ctypes.c_int), ('y', ctypes.c_int)]

class SIZE(ctypes.Structure):
    _fields_ = [('cx', ctypes.c_int), ('cy', ctypes.c_int)]

class RECT(ctypes.Structure):
    _fields_ = [('left', ctypes.c_int), ('top', ctypes.c_int), ('right', ctypes.c_int), ('bottom', ctypes.c_int)]

class SYSTEMTIME(ctypes.Structure):
    _fields_ = [('wYear', ctypes.c_ushort), ('wMonth', ctypes.c_ushort), 
                ('wDayOfWeek', ctypes.c_ushort), ('wDay', ctypes.c_ushort),
                ('wHour', ctypes.c_ushort), ('wMinute', ctypes.c_ushort),
                ('wSecond', ctypes.c_ushort), ('wMilliseconds', ctypes.c_ushort)]

class EventInit(ctypes.Structure):
    _fields_ = [('fake', ctypes.c_int)]
    
class EventExit(ctypes.Structure):
    _fields_ = [('fake', ctypes.c_int)]
    
class EventTimer(ctypes.Structure):
    _fields_ = [('uID', ctypes.c_uint)]

class EventScroll(ctypes.Structure):
    _fields_ = [('nSbCode', ctypes.c_int), ('nPos', ctypes.c_int), ('bVertical', ctypes.c_bool)]

class EventSpinValue2String(ctypes.Structure):
    '''strValue: SStringW'''
    _fields_ = [('bInit', ctypes.c_bool), ('nValue', ctypes.c_int), ('strValue', ctypes.c_uint)]

class EventSwndCreate(ctypes.Structure):
    _fields_ = [('fake', ctypes.c_int)]

class EventSwndInitFinish(ctypes.Structure):
    _fields_ = [('fake', ctypes.c_int)]

class EventSwndDestroy(ctypes.Structure):
    _fields_ = [('fake', ctypes.c_int)]

class EventSwndSize(ctypes.Structure):
    _fields_ = [('szWnd', SIZE)]

class EventSwndStateChanged(ctypes.Structure):
    _fields_ = [('dwOldState', ctypes.c_uint), ('dwNewState', ctypes.c_uint)]

class EventSwndVisibleChanged(ctypes.Structure):
    _fields_ = [('fake', ctypes.c_int)]

class EventSwndAnimationStart(ctypes.Structure):
    '''SAnimation(pAni)'''
    _fields_ = [('pAni', ctypes.c_uint)]

class EventSwndAnimationStop(ctypes.Structure):
    '''SAnimation(pAni)'''
    _fields_ = [('pAni', ctypes.c_uint)]

class EventSwndAnimationRepeat(ctypes.Structure):
    '''SAnimation(pAni)'''
    _fields_ = [('pAni', ctypes.c_uint)]

class EventKeyDown(ctypes.Structure):
    _fields_ = [('nChar', ctypes.c_uint), ('nFlags', ctypes.c_uint), ('bCancel', ctypes.c_bool)]

class EventSwndMouseLeave(ctypes.Structure):
    _fields_ = [('fake', ctypes.c_int)]

class EventSwndMouseHover(ctypes.Structure):
    _fields_ = [('fake', ctypes.c_int)]

class EventSwndUpdateTooltip(ctypes.Structure):
    '''strToolTip: SStringW'''
    _fields_ = [('strToolTip', ctypes.c_uint), ('bUpdated', ctypes.c_bool)]

class EventRadioGroupCheckChanged(ctypes.Structure):
    '''SWindow(pChecked)'''
    _fields_ = [('pChecked', ctypes.c_uint)]

class EventItemPanelRclick(ctypes.Structure):
    _fields_ = [('wParam', ctypes.c_uint), ('lParam', ctypes.c_uint)]

class EventItemPanelDbclick(ctypes.Structure):
    _fields_ = [('wParam', ctypes.c_uint), ('lParam', ctypes.c_uint)]

class EventItemPanelClick(ctypes.Structure):
    _fields_ = [('wParam', ctypes.c_uint), ('lParam', ctypes.c_uint)]

class EventItemPanelRclickUp(ctypes.Structure):
    _fields_ = [('wParam', ctypes.c_uint), ('lParam', ctypes.c_uint)]

class EventItemPanelClickUp(ctypes.Structure):
    _fields_ = [('wParam', ctypes.c_uint), ('lParam', ctypes.c_uint)]

class EventItemPanelHover(ctypes.Structure):
    _fields_ = [('wParam', ctypes.c_uint), ('lParam', ctypes.c_uint)]

class EventItemPanelLeave(ctypes.Structure):
    _fields_ = [('fake', ctypes.c_int)]

class EventLButtonDown(ctypes.Structure):
    _fields_ = [('pt', POINT)]

class EventLButtonUp(ctypes.Structure):
    _fields_ = [('pt', POINT)]

class EventCmd(ctypes.Structure):
    _fields_ = [('fake', ctypes.c_int)]

class EventCtxMenu(ctypes.Structure):
    _fields_ = [('pt', POINT), ('bCancel', ctypes.c_bool)]

class EventSetFocus(ctypes.Structure):
    _fields_ = [('wndOld', ctypes.c_uint)]

class EventSetFocus(ctypes.Structure):
    _fields_ = [('wndFocus', ctypes.c_uint)]

class EventScrollViewOriginChanged(ctypes.Structure):
    _fields_ = [('ptOldOrigin', POINT), ('ptNewOrigin', POINT)]

class EventScrollViewSizeChanged(ctypes.Structure):
    _fields_ = [('szOldViewSize', SIZE), ('szNewViewSize', SIZE)]

class EventOfEvent(ctypes.Structure):
    '''SEvtArgs(pOrgEvt)'''
    _fields_ = [('pOrgEvt', ctypes.c_uint)]

class EventOfPanel(ctypes.Structure):
    '''SWindow(pPanel), SEvtArgs(pOrgEvt)'''
    _fields_ = [('pPanel', ctypes.c_uint), ('pOrgEvt', ctypes.c_uint)]

class EventTabSelChanging(ctypes.Structure):
    _fields_ = [('uOldSel', ctypes.c_uint), ('uNewSel', ctypes.c_uint), ('bCancel', ctypes.c_bool)]

class EventTabSelChanged(ctypes.Structure):
    _fields_ = [('uOldSel', ctypes.c_uint), ('uNewSel', ctypes.c_uint)]

class EventTabItemHover(ctypes.Structure):
    _fields_ = [('iHover', ctypes.c_int)]

class EventTabItemLeave(ctypes.Structure):
    _fields_ = [('iLeave', ctypes.c_int)]

class EventLBSelChanging(ctypes.Structure):
    _fields_ = [('nNewSel', ctypes.c_int), ('nOldSel', ctypes.c_int), ('bCancel', ctypes.c_bool)]

class EventLBSelChanged(ctypes.Structure):
    _fields_ = [('nNewSel', ctypes.c_int), ('nOldSel', ctypes.c_int)]

class EventLBDbClick(ctypes.Structure):
    _fields_ = [('nCurSel', ctypes.c_int)]

class EventLVSelChanged(ctypes.Structure):
    _fields_ = [('iOldSel', ctypes.c_int), ('iNewSel', ctypes.c_int)]

class EventLVSelChanging(ctypes.Structure):
    _fields_ = [('iOldSel', ctypes.c_int), ('iNewSel', ctypes.c_int), ('bCancel', ctypes.c_bool)]

class EventTVSelChanged(ctypes.Structure):
    _fields_ = [('hOldSel', ctypes.c_ulong), ('hNewSel', ctypes.c_ulong)]

class EventTVSelChanging(ctypes.Structure):
    _fields_ = [('hOldSel', ctypes.c_ulong), ('hNewSel', ctypes.c_ulong), ('bCancel', ctypes.c_bool)]

class EventRENotify(ctypes.Structure):
    _fields_ = [('iNotify', ctypes.c_uint), ('pv', ctypes.c_void_p), ('hr', ctypes.c_long)]

class EventREMenu(ctypes.Structure):
    _fields_ = [('uCmd', ctypes.c_uint)]

class EventSliderPos(ctypes.Structure):
    _fields_ = [('nPos', ctypes.c_int)]

class EventHeaderClick(ctypes.Structure):
    _fields_ = [('iItem', ctypes.c_int)]

class EventHeaderItemChanging(ctypes.Structure):
    _fields_ = [('iItem', ctypes.c_int), ('nWidth', ctypes.c_int)]

class EventHeaderItemChanged(ctypes.Structure):
    _fields_ = [('iItem', ctypes.c_int), ('nWidth', ctypes.c_int)]

class EventHeaderItemSwap(ctypes.Structure):
    _fields_ = [('iOldIndex', ctypes.c_int), ('iNewIndex', ctypes.c_int)]

class EventHeaderRelayout(ctypes.Structure):
    _fields_ = [('fake', ctypes.c_int)]

class EventCBSelChange(ctypes.Structure):
    _fields_ = [('nCurSel', ctypes.c_int)]

class EventCBDropdown(ctypes.Structure):
    _fields_ = [('pDropDown', ctypes.c_void_p)]

class EventCBBeforeCloseUp(ctypes.Structure):
    _fields_ = [('bCloseBlock', ctypes.c_bool)]

class EventLCSelChanging(ctypes.Structure):
    _fields_ = [('nNewSel', ctypes.c_int), ('nOldSel', ctypes.c_int), ('bCancel', ctypes.c_bool)]

class EventLCSelChanged(ctypes.Structure):
    _fields_ = [('nNewSel', ctypes.c_int), ('nOldSel', ctypes.c_int)]

class EventLCDbClick(ctypes.Structure):
    _fields_ = [('nCurSel', ctypes.c_int)]

class EventLCItemDeleted(ctypes.Structure):
    _fields_ = [('nItem', ctypes.c_int), ('dwData', ctypes.c_uint)]

class EventCalendarSelDay(ctypes.Structure):
    _fields_ = [('wOldDay', ctypes.c_ushort), ('wNewDay', ctypes.c_ushort)]

class EventCalendarSetDate(ctypes.Structure):
    _fields_ = [('fake', ctypes.c_int)]

class EventCalendarExChanged(ctypes.Structure):
    _fields_ = [('iNewDay', ctypes.c_ushort), ('iNewMonth', ctypes.c_ushort), ('iNewYear', ctypes.c_ushort), ('nBtnType', ctypes.c_int)]

class EventDateTimeChanged(ctypes.Structure):
    _fields_ = [('newTime', SYSTEMTIME)]

class EventTCSelChanging(ctypes.Structure):
    _fields_ = [('hOldSel', ctypes.c_ulong), ('hNewSel', ctypes.c_ulong), ('bCancel', ctypes.c_bool)]

class EventTCSelChanged(ctypes.Structure):
    _fields_ = [('hOldSel', ctypes.c_ulong), ('hNewSel', ctypes.c_ulong)]

class EventTCCheckState(ctypes.Structure):
    _fields_ = [('hItem', ctypes.c_ulong), ('uCheckState', ctypes.c_uint)]

class EventTCExpand(ctypes.Structure):
    _fields_ = [('hItem', ctypes.c_ulong), ('bCollapsed', ctypes.c_bool)]

class EventTCDbClick(ctypes.Structure):
    _fields_ = [('hItem', ctypes.c_ulong), ('bCancel', ctypes.c_bool)]

class EventSplitPaneMoved(ctypes.Structure):
    _fields_ = [('rcPane', RECT)]

class EventImageAnimateStart(ctypes.Structure):
    _fields_ = [('fake', ctypes.c_int)]

class EventImageAnimateStop(ctypes.Structure):
    _fields_ = [('fake', ctypes.c_int)]

class EventSelectMenu(ctypes.Structure):
    _fields_ = [('nMenuId', ctypes.c_uint), ('pMenu', ctypes.c_void_p)]

class EventPopMenu(ctypes.Structure):
    _fields_ = [('nMenuIndex', ctypes.c_uint), ('pMenu', ctypes.c_void_p)]

class EventSetHotKey(ctypes.Structure):
    _fields_ = [('vKey', ctypes.c_ushort), ('wModifiers', ctypes.c_ushort)]

class EventSwitchChanged(ctypes.Structure):
    _fields_ = [('bTurnOn', ctypes.c_int), ('bCacnel', ctypes.c_bool)]

class EventCapture(ctypes.Structure):
    _fields_ = [('pt', POINT)]

class EventCaptureFinish(ctypes.Structure):
    _fields_ = [('pt', POINT)]
